package main;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import com.model.Person;
import com.model.Student;

public class ReflectionClassConstructor {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		String classPath = "com.model.Student";
		
		Class<?> reflectionClass = null;
		
		try {
			reflectionClass = Class.forName(classPath);
		} catch (ClassNotFoundException e) {
			System.out.println("Class not found!!!");
			e.printStackTrace();
		}
		
		// 1. OBTAINING CONTRUCTOR
		
		Constructor<?> constructor1 = null;
		Constructor<?> constructor2 = null;
		Constructor<?> constructor3 = null;
		
		try {
			constructor1 = reflectionClass.getDeclaredConstructor(String.class, String.class, int.class);
			constructor2 = reflectionClass.getDeclaredConstructor(String.class, String.class, int.class, double.class, double.class, double.class);
			constructor3 = reflectionClass.getDeclaredConstructor(Person.class, String.class);
		} 
		catch (NoSuchMethodException | SecurityException e) {
			System.out.println("Can not find any contructor such as you request!!!");
			e.printStackTrace();
		}
		
		
		// 2. INSTANTIATING OBJECT USING CONTRUCTOR OBJECT
		
		Object student1 = null;
		Object student2 = null;
		Student student3 = null;
		
		try {
			student1 = constructor1.newInstance("SV1", "Tony Teo",20);
			
			constructor2.setAccessible(true);
			student2 = constructor2.newInstance("SV2", "Victor Vu", 20, 10, 10, 10);
			
			constructor3.setAccessible(true);
			student3 = (Student) constructor3.newInstance(new Person("Songoku", 200), "SV3");
			student3.setMath(9.5);
			student3.setPhysical(9);
			student3.setChemistry(9);
			
			System.out.println("Student 1: " + student1.toString());
			System.out.println("Student 2: " + student2.toString());
			System.out.println("Student 3: " + student3.toString());
		} 
		catch (InstantiationException | IllegalAccessException
				| IllegalArgumentException | InvocationTargetException e) {
			System.out.println("Exception when creating instance of class!!!");
			e.printStackTrace();
		}
		
		// 3. GET CONSTRUCTOR PARAMETERS
		
		Class<?>[] constructorParameters1 = constructor1.getParameterTypes();
		
		for(Class<?> param : constructorParameters1){
			System.out.println("Parameter of constructor1: " + param.getName());
		}
		
		Class<?>[] constructorParameters2 = constructor2.getParameterTypes();
		
		for(Class<?> param : constructorParameters2){
			System.out.println("Parameter of constructor2: " + param.getName());
		}
		
		Class<?>[] constructorParameters3 = constructor3.getParameterTypes();
		
		for(Class<?> param : constructorParameters3){
			System.out.println("Parameter of constructor3: " + param.getName());
		}
	}

}
